<?php
define("WIKI_ROOT", "http://www.send2wiki.com/sp/");

class Send2Wiki extends SpecialPage
{
        function Send2Wiki() {
                SpecialPage::SpecialPage("Send2Wiki");
        }

        function execute( $par ) {
                global $wgRequest, $wgOut;

                self::loadMessages();
                $this->setHeaders();
		
		coslSend2Wiki();
        }

        function loadMessages() {
                static $messagesLoaded = false;
                global $wgMessageCache;
                if ( $messagesLoaded ) return;
                $messagesLoaded = true;

                require( dirname( __FILE__ ) . '/Send2Wiki.i18n.php' );
                foreach ( $allMessages as $lang => $langMessages ) {
                        $wgMessageCache->addMessages( $langMessages, $lang );
                }
        }
}

// callback function for the Send2Wiki special page that directs traffic
function coslSend2Wiki() {
   global $wgOut, $wgRequest, $wgUser;
   
   $wgOut->setPageTitle("Send2Wiki");

   // form was posted (do the Send2Wiki!)
   if ($wgUser->isLoggedIn() && $wgRequest->wasPosted()) sendPage2Wiki();

   // coming in from the bookmarklet
   else if ($wgRequest->getText("u") || isset($_COOKIE['s2w_uri']))
   {
      // get the uri and title from the query string
      $src_uri = $wgRequest->getText("u");
      $title = $wgRequest->getText("t");

      // logged in already      
      if ($wgUser->isLoggedIn()) showSend2WikiForm( $src_uri, $title );

      // need to login to send a page to the wiki
      else showLoginPage( $src_uri, $title );
   }
   // just visiting the page
   else showDocs();
}

// show a form for specifying the options for sending a page to the wiki (when we are coming in from the bookmarklet)
function showSend2WikiForm( $src_uri, $title ) {
   global $wgOut;

   if ($src_uri == "") {
      $src_uri = $_COOKIE['s2w_uri'];
      $title = $_COOKIE['s2w_title'];
   }
   // error page if the uri is not allowed
   if (!isAllowedUri( $src_uri )) {
      $wgOut->addHTML( '<p style="color:red;font-weight:bold">'.wfMsg('error_illegal_url').'</p>' );
      return;
   }
   // cleark the cookies
   clearSend2WikiCookies();
   
   // remove any illegal characters from the title   
   $title = cleanupTitle( $title, $src_uri );
         
   // a brief explanation
   $wgOut->addHTML( '<p>'.wfMsg( 'tagline' ).'</p>' );

   // fetch the web page
   $page_html = get_allowed_contents( $src_uri );

   // display other derivative works
   listDerivativeWorks( $src_uri );   

   // insert javascript
   $msg_must_specify_title = wfMsg('must_specify_title');
   $msg_must_specify_url = wfMsg('must_specify_url');
   $msg_must_specify_license_title = wfMsg('must_specify_license_title');
   $msg_must_specify_license_url = wfMsg('must_specify_license_url');
   $msg_must_check_permission = wfMsg('must_check_permission');
   $script = <<<SCRIPT
<script type="text/javascript">
function showOther(bShow)
{
   document.getElementById("other_details").style.display=(bShow?"block":"none");
}
function showAdvancedOptions(bShow)
{
   document.getElementById("simple_buttons").style.display = (bShow?"none":"block");
   document.getElementById("advanced_options").style.display = (bShow?"block":"none");
}
function previewLicense()
{
   window.open(document.getElementById("other_license_url").value);
   return false;
}
function validateForm()
{
   if (document.getElementById("t").value==""){alert("$msg_must_specify_title");return false;};
   var uri = document.getElementById("u");
   if (uri.value==""){alert("$msg_must_specify_url");return false;}
   else if (uri.value.indexOf('http') == -1) uri.value = "http://" + uri.value;
   if (document.getElementById("license_id").value == "-1")
   {
      if (document.getElementById("other_license_title").value==""){alert("$msg_must_specify_license_title");return false;};
      if (document.getElementById("other_license_url").value==""){alert("$msg_must_specify_license_url");return false;};
   }
   if (document.getElementById("permission").checked==false){alert("$msg_must_check_permission");return false;};
   return true;
}
function licenseChanged()
{
   showOther(document.getElementById("license_id").value=="-1");
   return false;
}
</script>

SCRIPT;
   $wgOut->addHTML( $script );
	 
   // display the form   
   $wgOut->addHTML('<form method="post" onsubmit="return validateForm();">');

   // page title
   $wgOut->addHTML('<p><strong>Title</strong><br/>');
   $wgOut->addHTML('<span style="color:gray">Title to give to the wiki page.</span><br/>');
   $wgOut->addHTML('<input type="text" id="t" name="t" size="120" value="'.$title.'"/></p>');
   $wgOut->addHTML('<input type="hidden" id="ot" name="ot" value="'.$title.'"/>');
   //$wgOut->addHTML('<p><strong>Tags</strong>: <input type="text" name="g" size="120" value="'.$s2w_tags.'"/></p>');

   // translation options
   $wgOut->addHTML( '<p><strong>'.wfMsg('translation_title').'</strong><br/><span style="color:gray">'.wfMsg('translation_tagline').'</span><br/>' );
   $wgOut->addHTML( '<select name="langpair">' );
   $wgOut->addHTML( wfMsg('translation_options') );
   $wgOut->addHTML( '</select></p>' );

   // try to detect the license
   $licenseInfo = extractLicense( $page_html, $src_uri );
   $licenseURI = $licenseInfo[0];
   $licenseTitle = $licenseInfo[1];

   // see if the license explicitly grants permission
   $permission = licenseGrantsPermission( $licenseURI );
   if ($permission) {
      // submit and advanced options buttons
      $wgOut->addHTML('<div id="simple_buttons">');
      $wgOut->addHTML('<p id="simple_buttons"><input type="submit" value="Send It!" /></p>');
      $wgOut->addHTML('<p><a href="javascript:void(null);" onclick="return showAdvancedOptions(true);" />'.wfMsg('options_show').'</a></p>');
      $wgOut->addHTML('</div>');
   
      // advanced options are hidden
      $wgOut->addHTML('<div id="advanced_options" style="display:none" >');
   }
   else {
      // advanced options are displayed
      $wgOut->addHTML('<div id="advanced_options" >');
   }
   
   // URL
   $wgOut->addHTML('<p><strong>'.wfMsg('url_title').'</strong><br/>');
   $wgOut->addHTML('<span style="color:gray">'.wfMsg('url_description').'</span><br/>');
   $wgOut->addHTML('<input type="text" id="u" name="u" size="120" value="'.$src_uri.'"/></p>');

   // let them choose the license for the wiki page         
   $wgOut->addHTML('<p style="margin-bottom:0px;"><strong>'.wfMsg('license_title').'</strong><br/>');
   $wgOut->addHTML('<span style="color:gray">'.wfMsg('license_description').'</span><br/>');

   $wgOut->addHTML('<select name="license_id" id="license_id" onchange="return licenseChanged();">');
   $bDetectedLicense = false;
   $dbr =& wfGetDB( DB_SLAVE );
   $res = $dbr->query( 'SELECT uri, id, title, uri = \''.sanitize_sql_string($licenseURI).'\' AS selected FROM send2wiki_licenses WHERE standard = 1 ORDER BY id' );
   while ($row = $dbr->fetchObject($res))
   {
      $wgOut->addHTML( $row->selected);
      if ($row->selected == 1)
      {
	 $bDetectedLicense = true;
	 $licenseURI = "";
	 $copyrightHolder = "";
      }
      $wgOut->addHTML('<option value="'.$row->id.'"'.($row->selected == 1 ? " selected" : "").'>'.$row->title.'</option>
      ');
   }
   $dbr->freeResult( $res );
   
   // select the other license if a license we know about was not detected
   if ($bDetectedLicense == true) $wgOut->addHTML('<option value="-1">'.wfMsg('license_other').'</option>');
   else $wgOut->addHTML('<option selected value="-1">'.wfMsg('license_other').'</option>');
   $wgOut->addHTML('</select><br/>');
   if ($bDetectedLicense == true) {
      $wgOut->addHTML(wfMsg('autodetected_license').': <a href="'.$licenseURI.'">'.$licenseTitle.'</a><br/>');
      $licenseTitle = "";
   }
   $wgOut->addHTML('</p>');
	 
   // "other" license details
   $wgOut->addHTML('<div id="other_details" style="margin-left:22px;margin-top:0px;'.($bDetectedLicense == true ? "display:none;" : "").'">');
   $wgOut->addHTML('<p><strong>'.wfMsg('license_title').'</strong><br/><input type="text" name="other_license_title" id="other_license_title" size="120" value="'.$licenseTitle.'"/></p>');
   $wgOut->addHTML('<p><strong>'.wfMsg('license_url').'</strong> (<a href="javascript:void(null)" onclick="return previewLicense();">preview</a>)<br/><input type="text" id="other_license_url" name="other_license_url" size="120" value="'.$licenseURI.'"/></p>');
   $wgOut->addHTML('</div>');
   $wgOut->addHTML('</p>');
	 
   // I have permission
   $wgOut->addHTML('<p><strong>'.wfMsg('permission_label').'</strong><br/><input type="checkbox" id="permission" name="permission" '.($bDetectedLicense == true ? "checked" : "").' />'.wfMsg('permission_explanation').'</p>');

   // submit button
   $wgOut->addHTML('<p><input type="submit" value="'.wfMsg('submit_button_label').'"/></p>');
   
   // hide advanced options
   if ($permission) $wgOut->addHTML('<p><a href="javascript:void(null);" onclick="return showAdvancedOptions(false);" />'.wfMsg('options_hide').'</a></p>');

   // end advanced options
   $wgOut->addHTML('</div>');

   // end the form
   $wgOut->addHTML('</form>');
}

// insert the page into the database and redirect to it
function sendPage2Wiki(){

   global $wgOut, $wgUser, $wgRequest;

   // get form data   
   $src_uri = $wgRequest->getText("u");
   $src_title = $wgRequest->getText("ot");
   $title = $wgRequest->getText("t");
   $license_id = $wgRequest->getText("license_id");

   // if the src and dest languages are not the same run the page through google translator
   $langpair = $wgRequest->getText("langpair");
   $languages = explode( "|", $langpair );
   $src_language = $languages[0];
   $dest_language = $languages[1];

   // make sure people aren't injecting SQL attacks into their urls   
   $src_uri = sanitize_sql_string( $src_uri );   

   // prepare data for new page
   $page_summary = "Created from $src_uri using Send2Wiki";
   $minoredit = false;
   $watchthis = false;
   $isComment = false;
   $page_title = Title::newFromText($title);
   $article = new Article($page_title);
 
   // don't let users overwrite pages they didn't create
   if ( !canOverwritePage( $wgUser->getID(), Title::newFromText(sanitize_sql_string($title))->getDBKey() )) {
      $wgOut->addHTML( '<p style="color:red;font-weight:bold">'.wfMsg('error_illegal_overwrite').'</p><p>'.wfMsg('error_illegal_overwrite_resolution').'</p>' );
      $wgOut->addWikiText( wfMsg('error_illegal_overwrite_goto').': [['.$title.']]' );
      return;
   }
   // error page if the uri is not allowed
   if (!isAllowedUri( $src_uri )) {
      $wgOut->addHTML( '<p style="color:red;font-weight:bold">'.wfMsg('error_illegal_url').'</p>' );
      return;
   }
   $wiki_text = "";
   
   // URL ends with pdf, assume it is a pdf
   if ( endsWith( $src_uri, '.pdf' ) ) {
   
      // convert the pdf to html
      $html = convert_pdf_to_html( $src_uri );

      // convert the web page to wiki syntax
      $wiki_text = convert_html_to_wiki( $src_uri, $html );
   }
   // not a pdf
   else {
   
      // see if we are coming from MIT
      if (beginsWith ( $src_uri, 'http://ocw.mit.edu/' ) ) {
	 $wiki_text = getMITPage( $src_uri, $src_language, $dest_language );
      }
      // not coming from MIT
      else {
      
         // see if we are coming from one of the wiki's we know about
         $wiki_name = getWikiName( $src_uri );
	 if ($wiki_name) {

	    // needs translated
	    if ( $src_language != $dest_language) {
	    
	       // it is one of the wikipedias
	       if (endsWith( getHost( $src_uri ), $src_language.'.wikipedia.org' ) ) {
	       
		  // retrieve the original web page chrome and all
		  $html = get_contents ( $src_uri );

		  // look for a link to the specified translation
		  $match = array();
		  if (preg_match( '/<a href="(http:\/\/'.$dest_language.'\.wikipedia\.org.*)">/', $html, $match )) {
		     $src_uri = $match[1];
		     $wiki_text = getTextFromWiki( $src_uri, $wiki_name );
		  }
	       }
	       if ( !$wiki_text ) {
		  // some wiki we don't know about, just get the print version
		  $html = get_translated_contents( $src_uri.'?printable=yes', $src_language, $dest_language );
		  
		  // extract just the content
		  $match = array();
		  if (preg_match( '/(<p>.*)<div class="printfooter">/sm', $html, $match )) {
		     $html = $match[1];
		  }
		  // convert the html towiki
		  $wiki_text = convert_html_to_wiki( $src_uri, $html );
	       }
	    }
	    // no translation needed
	    else {
      	       $wiki_text = getTextFromWiki( $src_uri, $wiki_name );
	    }
	 }
	 // not from MIT or a wiki 
	 else {
	 
	    // so retrieve the page as is, possibly translating it
	    $html = get_allowed_contents( $src_uri );
	    // comming from an educommons website
	    if ( fromEducommons( $html )) {
	       $wiki_text = getEducommonsPage( $src_uri, $html, $src_language, $dest_language );
	    }
		else if ( fromDrupal( $html )) {
	       $wiki_text = getDrupalPage( $src_uri, $html, $src_language, $dest_language );
		}
	    // just a plain web page
	    else {
	       if ( $src_language != $dest_language ) {
		  $html = get_translated_contents( $src_uri, $src_language, $dest_language );
	       }
	       $wiki_text = convert_html_to_wiki( $src_uri, $html );
	       }
	 }
      }
   }
   // get access to the DB
   $dbw =& wfGetDB(DB_MASTER);

   // the "other" license was specified
   if ($license_id == "-1") {
   
      // get the details
      $license_url = $wgRequest->getText("other_license_url");
      $license_title = $wgRequest->getText("other_license_title");
	    
      // try to look up the license
      $license_id = lookupLicenseID( $license_url );
      if ($license_id == "-1") {
	 // add the license to the database
	 $license_id = addLicense( $dbw, $license_url, $license_title );
      }
   }
   // the article already exists         
   if ($article->exists()) {
      // update the contents of the article
      $article->updateArticle($wiki_text, $page_summary, $minoredit, $watchthis);
   }
   else {
      // store the contents of the article	       
      $article->insertNewArticle($wiki_text, $page_summary, $minoredit, $watchthis, false, $isComment);
   }
   // see if we already have a send2wiki record for the article
   $send2WikiID = getSend2WikiID($article->getID());
   
   // we've got a send2wiki entry for this article
   if ($send2WikiID) {
      // update the send2wiki table in the DB
      $dbw->update('send2wiki', 
         array(
	    'user_id'=>$wgUser->getID(), 
	    'src_uri'=>$src_uri, 
	    'src_title'=>sanitize_sql_string( $src_title ), 
	    'derived_timestamp'=>wfTimestampNow(), 
	    'license_id'=>$license_id,
	    'src_language'=>$src_language, 
	    'dest_language'=>$dest_language
	    ), 
         array('id'=>$send2WikiID));
   }
   // no send2wiki entry for this article
   else {
      // add the article to the send2wiki table in the DB
      $dbw->insert('send2wiki', 
	 array(
	    'page_id'=>$article->getID(), 
	    'user_id'=>$wgUser->mId, 
	    'src_uri'=>$src_uri, 
	    'src_title'=>sanitize_sql_string( $src_title ), 
	    'derived_timestamp'=>wfTimestampNow(), 
	    'license_id'=>$license_id,
	    'src_language'=>$src_language,
	    'dest_language'=>$dest_language
	    ),
	 __METHOD__);
   }
   // let didly know what we did
   //addDidlies( $wgUser, $src_uri, $src_title, $article->mTitle );
}

function addDidlies( $user, $src_uri, $title, $article_title ) {
   global $wgArticlePath;

   $wiki_article_uri = WIKI_ROOT.'/index.php/'.urldecode($article_title->mUrlform);
   $wiki_article_title = $article_title->mPrefixedText;
   $wiki_user_title = $user->getRealName();

   $port = 80;
   $key = 'ae818703e2690f934fac8f47cff12c466367b38d';
   $wiki_user_uri = WIKI_ROOT.'/index.php/User:'.$user->mName;
   $didly = 'scrumdidilyumptio.us';
//   $port = 3000;
//   $key = '30a10023379c972a6256c86f73af3f5e3f9becd6'; // key on justin's machine
//   $wiki_user_uri = str_replace( '$1', 'User:'.$user->mName, WIKI_ROOT.$wgArticlePath );
//   $didly = '192.168.15.181';
   
   // creator
   $data = 'didily[from_uri]='.$wiki_article_uri;
   $data .= '&didily[from_title]='.$wiki_article_title;
   $data .= '&didily[relation]='.'was derived by';
   $data .= '&didily[to_uri]='.$wiki_user_uri;
   $data .= '&didily[to_title]='.$wiki_user_title;
   $data .= '&key='.$key;
   do_post_request( $didly, $port, '/didilies', $data );

   // derivative work
   $data = 'didily[from_uri]='.$wiki_article_uri;
   $data .= '&didily[from_title]='.$wiki_article_title ;
   $data .= '&didily[relation]='.'was derived from';
   $data .= '&didily[to_uri]='.$src_uri;
   $data .= '&didily[to_title]='.$title;
   $data .= '&key='.$key;
   
   do_post_request( $didly, $port, '/didilies', $data );
}

// show the send2wiki documentation and give users a way to get the bookmarklet
function showDocs(){
   global $wgOut;

   clearSend2WikiCookies();
//   $send2wiki_url = Title::newFromText('Special:Send2Wiki')->getFullURL();
   $send2wiki_url = WIKI_ROOT.'index.php/Special:Send2Wiki?';

   $bookmarklet = '<a href="javascript:e=encodeURIComponent;w=window;d=document;s=\''.$send2wiki_url.'\';location.href=s+\'u=\'+e(location)+\'&t=\'+e(d.title);"><strong>'.wfMsg('send2wiki_bookmarklet_label').'</strong></a>';   

   $wgOut->addHTML( wfMsg('send2wiki_docs', $bookmarklet) );
   $wgOut->addWikiText( wfMsg('send2wiki_docs_link') );
}

// get the host from a uri
function getHost( $uri ) {
   $parsed_uri = parse_url( $uri );
   if ( $parsed_uri ) return $parsed_uri['host'];
   else return null;
}

// detects that a web page is coming from a media wiki
function isWikiPage( $uri, $html ) {
   $host = getHost( $uri );
   if ( $host )
   {
      if ( preg_match( '/wikipedia\.org$/', $host ) != FALSE) return getWikiNameFromHost( $host );
      if ( strpos( $html, 'Powered by MediaWiki' ) != FALSE) return getWikiNameFromHost( $host );
   }
   return false;
}

// given a wiki uri, generates a uri needed to edit it (for retrieving wiki text)
function getWikiEditUri( $uri ) {
   return $uri.'?action=edit&editor=text';
}

// given a uri gets the wiki name from the interwiki table in the wikidb
function getWikiName( $uri ) {

   // find out where we are coming from
   $parsed_uri = parse_url( $uri );
   $host = $parsed_uri['host'];
   return getWikiNameFromHost( $host );
}

// given a host gets the wiki name from the interwiki table in the wikidb
function getWikiNameFromHost( $host ) {
   global $wgDBprefix;

   $dbr =& wfGetDB( DB_SLAVE );
   $sql = 'SELECT iw_prefix FROM '.$wgDBprefix.'interwiki WHERE iw_url LIKE \'http://'.sanitize_sql_string($host).'%\' LIMIT 1';
   $res = $dbr->query( $sql );
   $row = $dbr->fetchObject( $res );
   $wiki_name = $row ? $row->iw_prefix : "";
   $dbr->freeResult( $res );
   return $wiki_name;
}
// retrieves just the wiki text from a media wiki page
function getTextFromWiki( $uri, $wiki_name ) {

   // guess at the uri that we can use to get the edit version of the page (displaying wiki text in a textarea)
   $wiki_uri = getWikiEditUri( $uri );
   
   // get the html, translating it if needed
   $html = get_allowed_contents( $wiki_uri );
   
   // pull out the contents of the textarea
   $match = array();
   preg_match( '/<textarea[^>]*>(.*)<\/textarea>/sm', $html, $match );
   if ( $match ) {
      $wiki_text = $match[1];
      $wiki_text = preg_replace( '/\[\[([^\]]*)\]\]/', '[[:'.$wiki_name.':$1]]', $wiki_text );
      $wiki_text = preg_replace( '/:([^(\]\|\:)]*)]]/', ':$1|$1]]', $wiki_text );
      $wiki_text = preg_replace( '/&lt;/', '<', $wiki_text );
      $wiki_text = preg_replace( '/&gt;/', '>', $wiki_text );
      return $wiki_text;
   }
   // return the entire page, chrome and all if we don't find a textare
   else {
      return convert_html_to_wiki( $uri, $html );
   }
}

// copy a web page to a temp file and return the name of that file
function saveDataToTempFile( $uri, $html ) {

   global $wgUser;

   // generate a file name to store the web page
   $tempfname = tempnam( '/tmp', $wgUser->mName."_".urlencode( $uri ) );
  
   // write the html to a file
   $tempfile = fopen( $tempfname, 'w' );
   fwrite( $tempfile, $html );
   fclose( $tempfile );

   return $tempfname;
}

// shell out to the HTML::WikiConverter::MediaWiki perl script to convert the web page to mediawiki format
function convert_html_to_wiki( $src_uri, $html ) {

   // download the file
   $tempfname = saveDataToTempFile( $src_uri, $html );

   // execute a perl script to convert it to wiki format
   $src_uri = sanitize_system_string( $src_uri );
   $pipe = popen( "html2wiki --encoding utf-8 --dialect Send2Wiki --base-uri $src_uri --wiki-uri WIKI_ROOT $tempfname", 'r');
   while (! feof( $pipe ) ) {
      $output .= fgets($pipe);
   }
   pclose( $pipe );
  
   // delete the temp file
   unlink( $tempfname );
   
   // return the page in wiki format
   return $output;
}

// shell out to the pdftohtml utility to convert a pdf specified by uri to an html file
function convert_pdf_to_html( $src_uri ) {
//   set_magic_quotes_runtime(0);

   // generate a temp file name to save the pdf file to
   $tempfname = tempnam( '/tmp', $wgUser->mName."_".urlencode( $src_uri ) );

   // save the pdf to disk
   $fp = fopen( $src_uri, "rb" );
   if($fp){
      $tempfile = fopen( $tempfname, 'wb' );
      while(!feof($fp)) {
	 $data = fread($fp, 1024);
	 fwrite( $tempfile, $data );
      }
      fclose( $tempfile );
   }
   // execute the pdfhtml utility
   $html = '';
   $pipe = popen( "/usr/local/bin/pdftohtml -l 20 -noframes -stdout $tempfname", 'r');
   while (! feof( $pipe ) ) {
      $html .= fgets($pipe);
   }
   pclose( $pipe );

   // delete the temp file
   unlink( $tempfname );

   // return the html for the pdf
   return $html;
}

// clear the send2wiki browser cookies
function clearSend2WikiCookies() {

   setcookie( 's2w_uri', '', time() - 86400 );
   setcookie( 's2w_title', '', time() - 86400 );
}

// combine an absolute and relative urls into an absoute url
// borrowed from: http://www.thescripts.com/forum/thread3648.html
function combineUrls($absolute, $relative) {
   extract(parse_url($absolute));
   if($relative{0} == '/') {
      $cparts = array_filter(explode("/", $relative));
   }
   else {
      $aparts = array_filter(explode("/", $path));
      $rparts = array_filter(explode("/", $relative));
      $cparts = array_merge($aparts, $rparts);
      foreach($cparts as $i => $part) {
	 if($part == '.') {
	    $cparts[$i] = null;
	 }
	 if($part == '..') {
	    $cparts[$i - 1] = null;
	    $cparts[$i] = null;
	 }
      }
      $cparts = array_filter($cparts);
   }
   $path = implode("/", $cparts);
   $url = "";
   if($scheme) {
      $url = "$scheme://";
   }
   if($user) {
      $url .= "$user";
      if($pass) {
      $url .= ":$pass";
      }
      $url .= "@";
   }
   if($host) {
      $url .= "$host/";
   }
   $url .= $path;
   return $url;
}	

// automagically detect a license in a web page
function extractLicense( $text, $uri ) {

   // mit ocw is a special case
   if ( beginsWith( $uri, 'http://ocw.mit.edu/' ) ) {
      return array( "http://ocw.mit.edu/OcwWeb/Global/terms-of-use.htm", "MIT OCW License" );
   }
   
   // get a lower case version of the text for more efficient searching
   $ltext = strtolower($text);
   
   // declare some variables so we can use them
   $licenseURI;
   $licenseTitle;
   
   // cc rdf
   preg_match('/<rdf:rdf.*?<work.*?<license .*resource=["|\'](.*?)["|\'].*?<\/work>.*?<\/rdf:rdf>/sm', $ltext, $match);
   $licenseURI = $match ? $match[1] : null;
   
   // no cc rdf   
   if (!$licenseURI)
   {
      // get the head
      preg_match('/<head>(.*?)<\/head>.*?(<body.*?<\/body>)/smi', $text, $match);
      $head = $match[1];
      $body = $match[2];
      
      // copyright link
      preg_match('/(<link[^>]+rel=["|\']copyright["|\'].*?>)/smi', $head, $match);
      $copyrightLink = $match[1];
      if ($copyrightLink)
      {
         preg_match('/href=["|\'](.*?)["|\']/smi', $copyrightLink, $match);
	 $licenseURI = $match[1];
      }
      // look for a CC URL in the document
      if (!$licenseURI)
      {
	 // somehow the first regular expression didn't find the body
	 if (!$body)
	 {
	    preg_match('/(<body.*?<\/body>)/smi', $text, $match);
	    $body = $match[1];
	 }
         preg_match('/href=["|\'](http:\/\/creativecommons.org\/licenses.*?)["|\']/i', $body, $match);
	 $licenseURI = $match[1];
      }
      // copyright meta
      if ( !$licenseURI )
      {
	 preg_match('/(<meta[^>]+name=["|\']copyright["|\'].*?>)/smi', $head, $match);
	 $copyrightMeta = $match[1];
	 if ($copyrightMeta)
	 {
	    preg_match('/content=["|\'](.*?)["|\']/smi', $copyrightMeta, $match);
	    $licenseTitle = $match[1];
	    $licenseURI = $uri;
	 }
      }
      // copyright statement in the body
      if (!$licenseURI && !$licenseTitle)
      {
         preg_match('/<a[^>]+href=["|\']([^>]+?)["|\'][^<]*>copyright(.*?)<\/a>/smi', $body, $match);
	 $licenseURI = $match[1];
	 $licenseTitle = $match[2];

	 if (!$licenseURI)
	 {
	    preg_match('/<a[^>]+href=["|\']([^>]+?)["|\'][^>]*>([^<]*&copy;.*?)<\/a>/smi', $body, $match);
	    $licenseURI = $match[1];
	    $licenseTitle = $match[2];
	 }
/*	 if (!$licenseURI)
	 {
	    preg_match('/>(&copy;[^<]+)</smi', $body, $match);
	    $licenseTitle = $match[1];
	    $licenseURI = $uri;
	 }
*/
      }
      if ($licenseURI && strpos($licenseURI, "ttp") != 1) $licenseURI = combineUrls($uri, $licenseURI);
   }
   // if the license URI is already in the db, retreive its title from the db
   if ($licenseURI)
   {
      $licenseTitle = lookupLicenseTitle( $licenseURI );

      // if the license URI is not already in the db, try to retrieve the title from the license web page
      if (!$licenseTitle) $licenseTitle = getPageTitleFromURI( $licenseURI );
   }
   return array( $licenseURI, $licenseTitle );
}

// retrieve the contents of a uri (only if it is from an allowed ip address)
function get_allowed_contents( $uri ){
   if ( isAllowedUri( $uri )) return get_contents( $uri );
   else return "URL is not allowed: ".$uri;
}

// retrieve the contents of a uri
// you should call get_allowed_contents if not sure that the uri is allowed
function get_contents( $uri ){
   $context = array('http' => array ('header'=> 'User-agent: Send2Wiki 1.0', ),);
   $xcontext = stream_context_create($context);
   return file_get_contents( $uri, FALSE, $xcontext );
}

// retrieve the title of a web page given its uri
function get_translated_contents( $uri, $src_language, $dest_language ){

   // make sure an allowed uri was requested
   if ( !isAllowedUri( $uri )) return "URL is not allowed: ".$uri;
   
   // a translation was specified
   if ( $src_language != $dest_language ) {
      $uri = get_translation_uri( $uri, $src_language, $dest_language );
   }
   return get_contents( $uri );
}

// retrieve the title of a web page given its uri
function getPageTitle( $html ){
   preg_match('/<head>(.*?)<\/head>/smi', $html, $match);
   $head = $match[1];
   preg_match('/<title>(.*?)<\/title>/smi', $head, $match);
   $title = trim($match[1]);
   $nLineBreak = strpos($title, "\n");
   if ($nLineBreak != FALSE) $title = substr($title, 0, $nLineBreak);
   return trim($title);
}
function getPageTitleFromURI( $uri ){
   return getPageTitle( get_allowed_contents( $uri ) );
}

// given the URI of a license, see if it exists in the DB and return its ID
function lookupLicenseID( $licenseURI ){
   $dbr =& wfGetDB( DB_SLAVE );
   $res = $dbr->query( 'SELECT id FROM send2wiki_licenses WHERE uri = \''.sanitize_sql_string($licenseURI).'\' LIMIT 1' );
   $row = $dbr->fetchObject( $res );
   $licenseID = $row->id;
   $dbr->freeResult( $res );
   return $licenseID ? $licenseID : "-1";
}

// given the URI of a license, see if it exists in the DB and return its title if it does
function lookupLicenseTitle( $licenseURI ){
   $dbr =& wfGetDB( DB_SLAVE );
   $res = $dbr->query( 'SELECT title FROM send2wiki_licenses WHERE uri = \''.sanitize_sql_string($licenseURI).'\' LIMIT 1' );
   $row = $dbr->fetchObject( $res );
   $licenseTitle = $row->title;
   $dbr->freeResult( $res );
   return $licenseTitle;
}

// add a license to the database (when the user specifies an "other" license that isn't already in the db)
function addLicense( $dbw, $licenseURI, $licenseTitle ){
   $dbw->insert('send2wiki_licenses', array('uri'=>$licenseURI, 'title'=>$licenseTitle), __METHOD__);
   return $dbw->insertId();
}

// formats a timestamp for display
function timeString($timestamp){
   $year = substr($timestamp, 0, 4);
   $month = substr($timestamp, 4, 2);
   $day = substr($timestamp, 6, 2);
   $hour = substr($timestamp, 8, 2);
   $minute = substr($timestamp, 10, 2);
   $second = substr($timestamp, 12, 2);
   return date('H:m, d M Y', mktime($hour, $minute, $second, $month, $day, $year));
}

// display other derivative works of this same resource
function listDerivativeWorks( $src_uri ){
   global $wgOut, $wgUser, $wgDBprefix;

   // other wiki versions
   $dbr =& wfGetDB( DB_SLAVE );
   $res = $dbr->query( 'SELECT page_namespace, page_title, user_id, derived_timestamp FROM '.$wgDBprefix.'page INNER JOIN send2wiki ON '.$wgDBprefix.'page.page_id = send2wiki.page_id WHERE send2wiki.src_uri = \''.sanitize_sql_string($src_uri).'\'' );
   $row = $dbr->fetchObject( $res );
   if ( $row )
   {
      $wgOut->addHTML( '<p><strong>'.wfMsg('other_derivative_works_title').'</strong>' );
      $wgOut->addHTML( '<br/>'.wfMsg('other_derivative_works_description') );
      while( $row )
      {
	 // generate a link to the user that created the derived page
	 $deriver = User::newFromId($row->user_id);
	 $sk = $wgUser->getSkin();
	 $deriver_link = $sk->makeKnownLinkObj( $deriver->getUserPage(), $deriver->getRealName() );

	 // output a link to the derived page
	 $wgOut->addWikiText( '* [['.str_replace( '_', ' ', $row->page_title ).']] (derived by [[User:'.$deriver->getName().'|'.$deriver->getName().']] '.timeString($row->derived_timestamp).')' );
	 
	 // get the next derived work
	 $row = $dbr->fetchObject( $res );
      }
   }
   $dbr->freeResult( $res );
}

// make sure that the requested uri is not inside our network
function isAllowedUri( $uri ){
   if ( beginsWith($uri, 'http://ocw.usu.edu/') ||
        beginsWith($uri, WIKI_ROOT) ) return true;

   $parsed_uri = parse_url( $uri);
   if ( $parsed_uri ) {
      $host = $parsed_uri['host'];
      $ip = gethostbyname( $host );
      $match = array();
      preg_match( "/^(10\.|192\.168|172\.|127\.)/", $ip, $match );
      return !$match || $match[0] == null;
   }
   return false;
}

// check the web page html for the signature educommons logo
function fromEducommons( $html ){
   return strpos( $html, 'skinless_view' ) != false;
}

// check the web page html for the signature drupal javascript
function fromDrupal( $html ){
   return strpos( $html, 'drupal.js">' ) != false;
}

// cleanup titles
function cleanupTitle( $title, $uri ) {
   if (isWikiPage( $uri, '' )) return preg_replace ( '/ -.*$/', '', $title );
   else return preg_replace ( '/\|/', '-', $title );
}

// strip the chrome from MIT's web pages
function getMITPage( $uri, $src_language, $dest_language ) {

   // get the html, translating it if needed
   $html = get_translated_contents( $uri, $src_language, $dest_language );
   
   // strip the chrome
   $match = array();
   preg_match('/(<h1.*?)<div class=\"logo/sm', $html, $match);
   $body_html = $match[1];
   
   // convert the html to wiki format
   return convert_html_to_wiki( $uri, $body_html );
}

// strip the chrome from a drupal page
function getDrupalPage( $uri, $html, $src_language, $dest_language ) {

   // strip the chrome
   $match = array();
   preg_match('/<div id="main".*(<div class="content".*)<div class="links"/sm', $html, $match);
   if ($match) {
	   $body_html = $match[1];
   }
   // convert the html to wiki format
   return convert_html_to_wiki( $uri, $body_html );
}

// request the skinless view of the web page
function getEducommonsPage( $uri, $html, $src_language, $dest_language ) {

   // see if we can find a link to a skinless view
   $match = array();
   preg_match('/<a href="([^"]*skinless_view)"/sm', $html, $match);
   if ($match) {
      $uri = $match[1];
   }
   // get the html translating it if needed
   $html = get_translated_contents( $uri, $src_language, $dest_language );
   
   // strip the footer
   preg_match('/(<html.*)<div class="documentByLine"/sm', $html, $match);
   if ($match) {
      $html = $match[1].'</body></html>';
   }
   // convert the html to wiki format
   return convert_html_to_wiki( $uri, $html );
}

// checks to see if the license grants expicit permission to create derivative works
function licenseGrantsPermission( $uri ) {
   $dbr =& wfGetDB( DB_SLAVE );
   $res = $dbr->query( 'SELECT permission FROM send2wiki_licenses WHERE uri = \''.sanitize_sql_string($uri).'\' LIMIT 1' );
   $row = $dbr->fetchObject( $res );
   $permission = ($row && $row->permission == 1);
   $dbr->freeResult( $res );
   return $permission;
}

// see if url from mit
function isMITUrl( $uri ){
  $match = array();
   preg_match( '/http:\/\/ocw.mit.edu/', $uri, $match );
   return $match[0] != null;
}

// sees if a string ends with a specified string
function endsWith( $str, $sub ) {
   return ( substr( $str, strlen( $str ) - strlen( $sub ) ) == $sub );
}

// sees if a string begins with a specified string
function beginsWith( $str, $sub ) {
   return ( substr( $str, 0, strlen( $sub ) ) == $sub );
}

// sees if user can overwrite specified page
function canOverwritePage( $user_id, $title ) {
   global $wgDBprefix;
	
   $dbr =& wfGetDB( DB_SLAVE );
   $sql = 'SELECT user_id = '.$user_id.' AS owns
			FROM '.$wgDBprefix.'page 
			LEFT JOIN send2wiki ON '.$wgDBprefix.'page.page_id = send2wiki.page_id
			WHERE page_title = \''.$title.'\''; 
   $res = $dbr->query( $sql );
   $row = $dbr->fetchObject( $res );
   $can_overwrite = (!$row || $row->owns == 1) ? true : false;
   $dbr->freeResult( $res );
   return $can_overwrite;
}

// get translation url
function get_translation_uri( $uri, $src_language, $dest_language ) {
   return 'http://translate.google.com/translate_p?u='.$uri.'&langpair='.$src_language.'%7C'.$dest_language.'&hl=en&ie=UTF-8&oe=UTF-8&prev=%2Flanguage_tools';
}

// get the send2wiki ID for a specified article
function getSend2WikiID($pageID){
   $dbr =& wfGetDB( DB_SLAVE );
   $res = $dbr->query( 'SELECT id FROM send2wiki WHERE page_id = \''.$pageID.'\' LIMIT 1' );
   $row = $dbr->fetchObject( $res );
   $id = $row->id;
   $dbr->freeResult( $res );
   return $id;
}

// show the login page (when people are coming in from the bookmarklet and haven't logged in yet)
function showLoginPage( $uri, $title ) {
   global $wgOut, $wgRequest;

   $wgOut->addHTML('<p style="font-size:large;font-weight:bold">'.wfMsg('must_login').'</p>');
   $wgRequest->appendQuery( 'returnto=Special:Send2Wiki' );
   wfSetupSession();
   $loginForm = new LoginForm($wgRequest);
   $loginForm->mReturnTo = 'Special:Send2Wiki';
   $loginForm->mainLoginForm( '' );

   setcookie( 's2w_uri', $uri, time() + 86400 );
   setcookie( 's2w_title', $title, time() + 86400 );

   $wgOut->setPageTitle("Login Required");
}

// copied from: http://www.phpbuilder.com/columns/sanitize_inc_php.txt
// sanitize a string for SQL input (simple slash out quotes and slashes)
function sanitize_sql_string($string, $min='', $max='')
{
  $pattern[0] = '/(\\\\)/';
  $pattern[1] = "/\"/";
  $pattern[2] = "/'/";
  $replacement[0] = '\\\\\\';
  $replacement[1] = '\"';
  $replacement[2] = "\\'";
  $len = strlen($string);
  if((($min != '') && ($len < $min)) || (($max != '') && ($len > $max)))
    return FALSE;
  return preg_replace($pattern, $replacement, $string);
}

// copied from: http://www.phpbuilder.com/columns/sanitize_inc_php.txt
// sanitize a string in prep for passing a single argument to system() (or similar)
function sanitize_system_string($string, $min='', $max='')
{
  $pattern = '/(;|\||`|>|<|&|^|"|'."\n|\r|'".'|{|}|[|]|\)|\()/i'; // no piping, passing possible environment variables ($),
                           // seperate commands, nested execution, file redirection, 
                           // background processing, special commands (backspace, etc.), quotes
                           // newlines, or some other special characters
  $string = preg_replace($pattern, '', $string);
  $string = '"'.preg_replace('/\$/', '\\\$', $string).'"'; //make sure this is only interpretted as ONE argument
  $len = strlen($string);
  if((($min != '') && ($len < $min)) || (($max != '') && ($len > $max)))
    return FALSE;
  return $string;
}

function debug($msg){
   $fh = fopen("/tmp/wiki.log","a");
   fwrite($fh, $msg."\n");
   fclose($fh);
}

// do an http post request
// found on: http://netevil.org/node.php?nid=937
function do_post_request( $host, $port, $path, $data, $optional_headers = null ) {
//   debug($host);
//   debug($path);
   $content_length = strlen($data);
   $headers= "POST $path HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: $host\r\nUser-Agent: Send2Wiki\r\nContent-length: $content_length\r\n\r\n";
//   debug($data);
   $fp = fsockopen($host, $port, $errno, $errstr);
   if (!$fp) {
      return false;
   }
   fputs($fp, $headers);
   fputs($fp, $data);
   $ret = "";
   while (!feof($fp)) {
      $ret.= fgets($fp, 1024);
   }
   fclose($fp);
//   debug($ret);
   return $ret;
} 

/*
// uses google translation through their form
function translate_text( $wiki_text, $src_language, $dest_language ) {
   $wiki_text = str_replace( '&lt;', '<', $wiki_text );
   $wiki_text = str_replace( '&gt;', '>', $wiki_text );

   $data = 'langpair='.$src_language.'|'.$dest_language.'&hl=en&text='.urlencode($wiki_text);

   $html = urldecode(do_post_request( 'translate.google.com', '/translate_t', $data ));

   $match = array();
   preg_match( '/<div id=result_box dir=ltr>(.*)<\/div>/', $html, $match );
   if ( $match ) {
      $wiki_text = $match[1];
//      $wiki_text = str_replace( '&#39;', "\r\n", $wiki_text);
//      $wiki_text = str_replace( '&lt;', '<', $wiki_text );
//      $wiki_text = str_replace( '&gt;', '>', $wiki_text );
   }
   return $wiki_text;
}
*/

?>